﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;

namespace TechProg
{
  public partial class Form2 : Form
  {

    public Form2()
    {
      InitializeComponent();
      dataGridView1.Rows.Add();
      dataGridView1.AllowUserToAddRows = false;
      dataGridView1.AllowUserToDeleteRows = false;
    }

    bool k = false;// для закрытия формы
    RunTuring RunClass = new RunTuring();
    int Position = 0;
    int TypeOfWork = 0;

    private void Form2_FormClosing_1(object sender, FormClosingEventArgs e)
    {
      if (k == false)
      {
        e.Cancel = false;
        var result = MessageBox.Show("Вы уверены что хотите выйти из программы?", "Машина Тьюринга", MessageBoxButtons.YesNo);
        if (result == DialogResult.Yes)
        { }
        else
          e.Cancel = true;
      }
    }

    private void выходToolStripMenuItem_Click(object sender, EventArgs e)
    {
      var result1 = MessageBox.Show("Вы уверены что хотите выйти из программы?", "Машина Тьюринга", MessageBoxButtons.YesNo);
      if (result1 == DialogResult.Yes)
      { k = true; Close(); }
    }

    int r = 4; //счетчик столбцов т к 3 состояния у нас уже есть
    int t = 4;//счетчик строк т к 3 символа у нас уже есть
    int s = 4;//счетчик ленты


    private void Form2_Load(object sender, EventArgs e)
    {
      start();
    }
    private void start()
    {
      dataGridView2.Rows.Clear();
      dataGridView2.Rows.Add("_");
      dataGridView2.Rows.Add("1");
      dataGridView2.Rows.Add("*");
      RunClass.alphabet[0] = '_';
      RunClass.alphabet[1] = '1';
      RunClass.alphabet[2] = '*';
    }

    private void button4_Click(object sender, EventArgs e)
    {
      if (r == 16) MessageBox.Show("Допустимо не более 15 состояний!");
      else
      {
        dataGridView2.Columns.Add("Column" + Convert.ToString(r + 4), Convert.ToString(r));
        r = r + 1;
      }
    }

    private void button5_Click(object sender, EventArgs e)
    {
      dataGridView2.Columns.Remove("Column" + Convert.ToString(r + 3));
      r = r - 1;
    }

    private void button8_Click(object sender, EventArgs e)
    {

        if (t == 6) MessageBox.Show("Допустимо не более 5 символов!");
        else
        {
            dataGridView2.Rows.Add();
            t = t + 1;
        }
     
    }

    /*private void button6_Click(object sender, EventArgs e)
    {
      //тут еще надо добавить кучу проверок
      //обращение к ячейкам
      if ((textBox2.Text == "") && (textBox3.Text == "") && (textBox4.Text == "")) MessageBox.Show("Заполните поля!");
      else
      {
        int n = 0, m = 0;
        try
        {
          n = Convert.ToInt32(textBox3.Text); //строка
          m = Convert.ToInt32(textBox4.Text);  //столбец
        }
        catch
        {
          MessageBox.Show("Поля \"Строка\" и \"Столбец\" должны содержать только числа!");
          return;
        }
        string s = textBox2.Text; //содержимое

        if ((m > (r - 1)) || (n > (t - 1))) MessageBox.Show("Сивола не существует!");
        else
        {
          dataGridView2.Rows[n - 1].Cells[m].Value = s;
          RunClass.AddRule(dataGridView2[0, n - 1].Value.ToString()[0], s.Substring(0, 1),
            Convert.ToInt32(dataGridView2.Columns[m].HeaderCell.Value.ToString()), Convert.ToInt32(s.Substring(2, 1)), s[1]);
        }

      }
    }*/

    private void button7_Click(object sender, EventArgs e)
    {
      char tmp;
      for (int i = 0; i < dataGridView1.ColumnCount; i++)
      {
        try
        {
          tmp = dataGridView1[i, 0].Value.ToString()[0];
        }
        catch
        {
          dataGridView1[i, 0].Value = "_";
          tmp = '_';
        }
        if (RunClass.CheckAlphabet(tmp) == 0)
        {
          MessageBox.Show("Символ \"" + tmp + "\" отсутствует в алфавите");
          return;
        }
        else
        {
          RunClass.lenta[i + 1] = tmp;
        }
        if (RunClass.LentaLength != dataGridView1.ColumnCount)
        {
          RunClass.LentaLength = dataGridView1.ColumnCount;
        }
      }
    
    }

    public void UpdateTape()
    {
      for (int i = 0; i < RunClass.LentaLength; i++)
      {
        if (i < s - 1)
        {
          dataGridView1[i, 0].Value = RunClass.lenta[i];
        }
        else
        {
          dataGridView1.Columns.Add("Column" + s.ToString(), s.ToString());
          dataGridView1[i, 0].Value = RunClass.lenta[i];
          s++;
        }
      }
    }


    

    private void button11_Click(object sender, EventArgs e)
    {
      if (s < 2) MessageBox.Show("Лента должна иметь хотя бы одну ячейку");
      else
      {
        dataGridView1.Columns.Remove("Column" + Convert.ToString(s - 1));
        s = s - 1;
      }
    }

    public void UnselectTape()
    {
      for(int i = 0; i< dataGridView1.Columns.Count;i++)
        dataGridView1[i, 0].Selected = false;
    }

    public void TimerEventProcessor(Object myObject,
                                            EventArgs myEventArgs)
    {
      // Displays a message box asking whether to continue running the timer.
      UnselectTape();
      dataGridView1[RunClass.Position, 0].Selected = true;
      string condition = dataGridView1[Position, 0].Value.ToString();
      int tmp;
      tmp = RunClass.step();
      if (tmp == 1)
      {
        timer1.Stop();
        MessageBox.Show("Лента не может быть больше 10000!\r\nВыполнение остановлено.");
        RunClass.FirstStep = true;
      }
      else if (tmp == 2)
      {
        timer1.Stop();
        MessageBox.Show("Не найдено правило по данному состоянию\r\nВыполнение остановлено.");
        RunClass.FirstStep = true;
      }
      UpdateTape();
      if (RunClass.Condition == 0)
      {
        timer1.Stop();
        MessageBox.Show("Алгоритм перешел в последнее состояние\r\nВыполнение остановлено.");
        RunClass.FirstStep = true;
      }
    }


  

    private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {

    }

    private void алфавитToolStripMenuItem_Click(object sender, EventArgs e)
    {

    }

    private void pictureBox1_Click(object sender, EventArgs e)
    {
      if (TypeOfWork == 0)
      {
        for (; ; )
        {
          int tmp;
          tmp = RunClass.step();
          if (tmp == 1)
          {
            MessageBox.Show("Лента не может быть больше 100");
            RunClass.FirstStep = true;
            break;
          }
          else if (tmp == 2)
          {
            MessageBox.Show("Не найдено правило по данному состоянию");
            RunClass.FirstStep = true;
            break;
          }
          UpdateTape();
          dataGridView1[RunClass.Position, 0].Selected = true;
          if (RunClass.Condition == 0)
          {
            MessageBox.Show("Алгоритм перешел в последнее состояние");
            RunClass.FirstStep = true;
            break;
          }
        }
      }
      else
      {
        timer1.Interval = Convert.ToInt32(textBox1.Text);
        timer1.Enabled = true;
        timer1.Start();
        timer1.Tick += new EventHandler(TimerEventProcessor);
      }
    }

    private void pictureBox2_Click(object sender, EventArgs e)
    {
        timer1.Stop();
    }

    private void pictureBox3_Click(object sender, EventArgs e)
    {
        UnselectTape();
        if (TypeOfWork == 0)
        {
          label1.Visible = true;
          textBox1.Visible = true;
          TypeOfWork = 1;
        }
        else
        {
          label1.Visible = false;
          textBox1.Visible = false;
          TypeOfWork = 0;
        }
      
    }

  

    private void button10_Click(object sender, EventArgs e)
    {

    }

    private void pictureBox4_Click(object sender, EventArgs e)
    {
      if (s == 10001) MessageBox.Show("Допустимая длина ленты, не более 10000 элементов");
      else
      {
        dataGridView1.Columns.Add("Column" + s.ToString(), s.ToString());
        s = s + 1;
      }
    }

  

    private void pictureBox5_Click(object sender, EventArgs e)
    {
        if (s < 2) MessageBox.Show("Лента должна иметь хотя бы одну ячейку");
        else
        {
            dataGridView1.Columns.Remove("Column" + Convert.ToString(s - 1));
            s = s - 1;
        }
    }

    private void лентаToolStripMenuItem_Click(object sender, EventArgs e)
    {
        var saveFileDialog1 = new SaveFileDialog
         {
                Filter = @"AMT files (*.amt)|*.amt",
                Title = @"Сохранить файл"
        };
       
        saveFileDialog1.ShowDialog();
        if (saveFileDialog1.FileName != "")
            {
            using (var fileStream = (FileStream)saveFileDialog1.OpenFile())
                {
                    var binaryFormatter = new BinaryFormatter();
                    /*RunClass.OurRules[0].currentSymbol;
                    RunClass.OurRules[0].direction;
                    RunClass.OurRules[0].newSymbol;
                    |
                    RunClass.OurRules[0].nextCondition;
                    |
                    RunClass.OurRules[0].prevCondition;
                    |*/
                    binaryFormatter.Serialize(fileStream, dataGridView2.Rows);//отшибка. тут надо строки в массив пихать и сериализовать
                }
             }
               
    }

    private void pictureBox6_Click(object sender, EventArgs e)
    {
      uint Operand1 = 0;
      uint Operand2 = 0;
        Operand f = new Operand();          
        f.ShowDialog();
        if (f.DialogResult == DialogResult.OK)
        {
          Operand1 = f.Oper1();
          Operand2 = f.Oper2();
        }
        RunClass.lenta = new char[10000];
        for (int i = 0; i < 100; i++)
        {
          RunClass.lenta[i] = '_';
        }
        uint pos = 0;
        for (uint i = 0; i < Operand1; i++)
        {
          RunClass.lenta[i] = '1';
          RunClass.LentaLength++;
          pos = i;
        }
        pos++;
        RunClass.lenta[pos] = '*';
        RunClass.LentaLength++;
        pos++;
        for (uint i = pos; i < Operand2 + pos; i++)
        {
          RunClass.lenta[i] = '1';
          RunClass.LentaLength++;
        }
        UpdateTape();
    }

    private void button9_Click(object sender, EventArgs e)
    {
        var result2 = MessageBox.Show("Будет удалена выделенная строка. Вы уверены что хотете её удалить?", "Машина Тьюринга", MessageBoxButtons.YesNo);
        if (result2 == DialogResult.Yes)
        {
            if (t < 5) MessageBox.Show("Алгоритм должен иметь хотя бы три символа");
            else
            {
                dataGridView2.Rows.Remove(dataGridView2.CurrentRow);
                t = t - 1;
            }
        }
      
    }

    private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
      //тут еще надо добавить кучу проверок
      //обращение к ячейкам
      /*if ((textBox2.Text == "") && (textBox3.Text == "") && (textBox4.Text == "")) MessageBox.Show("Заполните поля!");
      else
      {
        int n = 0, m = 0;
        try
        {
          n = Convert.ToInt32(textBox3.Text); //строка
          m = Convert.ToInt32(textBox4.Text);  //столбец
        }
        catch
        {
          MessageBox.Show("Поля \"Строка\" и \"Столбец\" должны содержать только числа!");
          return;
        }
        string s = textBox2.Text; //содержимое

        if ((m > (r - 1)) || (n > (t - 1))) MessageBox.Show("Сивола не существует!");
        else
        {
          dataGridView2.Rows[n - 1].Cells[m].Value = s;
          RunClass.AddRule(dataGridView2[0, n - 1].Value.ToString()[0], s.Substring(0, 1),
            Convert.ToInt32(dataGridView2.Columns[m].HeaderCell.Value.ToString()), Convert.ToInt32(s.Substring(2, 1)), s[1]);
        }

      }*/
      if (dataGridView2.SelectedCells[0].Value != null)
      {
        try
        {
          bool correct = false;
          for (int i = 0; i < RunClass.alphabet.Length; i++)
          {
            if (dataGridView2[0, dataGridView2.CurrentCellAddress.X].Value.ToString()[0] == RunClass.alphabet[i])
              correct = true;
          }
          if (!correct)
            throw new Exception();
          correct = false;
          for (int i = 0; i < RunClass.alphabet.Length; i++)
          {
            if (dataGridView2.SelectedCells[0].Value.ToString()[0].Equals(RunClass.alphabet[i]))
              correct = true;
          }
          if (!correct)
            throw new Exception();
          if (!dataGridView2.SelectedCells[0].Value.ToString()[1].Equals('R') & !dataGridView2.SelectedCells[0].Value.ToString()[1].Equals('L') &&
            !dataGridView2.SelectedCells[0].Value.ToString()[1].Equals('N'))
            throw new Exception();
          RunClass.AddRule(dataGridView2[0, dataGridView2.CurrentCellAddress.Y].Value.ToString()[0],
                            dataGridView2.SelectedCells[0].Value.ToString()[0],
                            dataGridView2.CurrentCellAddress.X,
                            Convert.ToInt16(dataGridView2.CurrentCell.Value.ToString()[2])-48,
                            dataGridView2.SelectedCells[0].Value.ToString()[1]);
        }
        catch
        {
          MessageBox.Show("Ошибка ввода");
          dataGridView2.CurrentCell.Value = null;
        }
      }
    }

    private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {

    }

    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
      if (dataGridView1.SelectedCells[0].Value != null)
      {
        try
        {
          bool correct = false;
          if (dataGridView1.SelectedCells[0].Value.ToString().Length > 1)
            throw new Exception();
          for (int i = 0; i < RunClass.alphabet.Length; i++)
          {
            if (dataGridView1.SelectedCells[0].Value.ToString()[0].Equals(RunClass.alphabet[i]))
              correct = true;
          }
          if (!correct)
            throw new Exception();
          RunClass.lenta[dataGridView1.CurrentCellAddress.X] = dataGridView1.SelectedCells[0].Value.ToString()[0];
        }
        catch
        {
          MessageBox.Show("Ошибка ввода");
          dataGridView1.CurrentCell.Value = null;
        }
      }
    }

    private void нОДToolStripMenuItem_Click(object sender, EventArgs e)
    {

    }
  }

}
       
 

